#include "GameMap.h"

#include <exception>

#include "Logger.h"

namespace OOInterface
{

GameMap::GameMap( unsigned int width, unsigned int height ) :
	_width( width ), _height( height ), _landTiles(0), _gravity(0.0f),
	_tidalStrength(0.0f), _maxWindSpeed(0.0f), _minWindSpeed(0.0f),
	_consumableResources(), _density()
{
	_elevation = new float[ width * height ];
}

GameMap::GameMap( const GameMap& g ) :
	_width( g._width ), _height( g._height ), _landTiles(0), _gravity(g._gravity),
	_tidalStrength(g._tidalStrength), _maxWindSpeed(g._maxWindSpeed), _minWindSpeed(g._minWindSpeed),
	_consumableResources( g._consumableResources ), _elevation( g._elevation ), _density( g._density )

{
}

GameMap::~GameMap()
{
}



void GameMap::setElevation( unsigned int x, unsigned int y, float height )
{
	if( height < 0.0f )
		_landTiles -= 1;
	else
		_landTiles += 1;

	_elevation[ convertToIndex( x, y ) ] = height;
}

float GameMap::getElevation( unsigned int x, unsigned int y ) const
{
	return _elevation[ convertToIndex( x, y ) ];
}

void GameMap::setResourceDensity( const Resource& r, unsigned int x, unsigned int y, float density )
{
	if( _density.find( r ) == _density.end() )
	{
		DensityMapPtr newDensityMap( new DensityMap() );
		_density.insert( std::pair< Resource, DensityMapPtr >(r, newDensityMap ));
	}

	DensityMapPtr densityMap = (*_density.find( r )).second;

	DensityMap::iterator it = densityMap->find( convertToIndex( x, y ));

	if(it != densityMap->end())
	{
		(*it).second = density;
	}
	else
	{
		densityMap->insert( std::pair< int, float >( convertToIndex( x, y ), density ));
	}

}

float GameMap::getResourceDensity( const Resource& r, unsigned int x, unsigned int y) const
{
	ResourceDensityMap::const_iterator it = _density.find( r );

	if( it != _density.end() )
	{
		DensityMap::const_iterator it2 = it->second->find( convertToIndex( x, y ));

		if( it2 != it->second->end() )
			return it2->second;
	}

	return 0.0f;
}

void GameMap::addConsumableResource( ConstUnitPtr resource )
{
	_consumableResources.insert( resource );
}

void GameMap::removeConsumableResource( ConstUnitPtr resource )
{
	_consumableResources.erase( resource );
}

const ConsumableResourceSet& GameMap::getConsumableResources( ) const
{
	return _consumableResources;
}

}
